#include <func.h>

//生产者，消费者,通过计数信号量实现
int main()
{
    //获取key为1000的信号量集合
    int semArrid=semget(2000,2,IPC_CREAT|0600);
    ERROR_CHECK(semArrid,-1,"semget");
  
    unsigned short arr[2] = {0,10};//0代表产品数目为0，仓库数目为10
    int ret = semctl(semArrid,0,SETALL,arr);//第二参数是无效的
    ERROR_CHECK(ret,-1,"semctl SETALL");


    if(!fork())
    {
        struct sembuf P;
        P.sem_num = 0;//信号量值在集合中的下标
        P.sem_op = -1;//信号量值修改
        P.sem_flg = SEM_UNDO;//如果P操作被终止，会自动恢复
        struct sembuf V;
        V.sem_num = 1;//信号量值在集合中的下标
        V.sem_op = 1;//信号量值修改
        V.sem_flg = SEM_UNDO;//如果V操作被终止，会自动恢复
        //子进程是消费者
        while(1){
            sleep(2);
            printf("I am consumer, before consume, product = %d, space = %d\n",
                semctl(semArrid,0,GETVAL),semctl(semArrid,1,GETVAL));
            semop(semArrid,&P,1);//p的是0号信号量
            printf("Buy a product\n");
            semop(semArrid,&V,1);//v的是1号信号量
            printf("I am consumer, after consume, product = %d, space =%d\n",
                semctl(semArrid,0,GETVAL),semctl(semArrid,1,GETVAL));
        }
    }else
    {
        //父进程是生产者
        struct sembuf P;
        P.sem_num = 1;//信号量值在集合中的下标
        P.sem_op = -1;//信号量值修改
        P.sem_flg = SEM_UNDO;//如果P操作被终止，会自动恢复
        struct sembuf V;
        V.sem_num = 0;//信号量值在集合中的下标
        V.sem_op = 1;//信号量值修改
        V.sem_flg = SEM_UNDO;//如果V操作被终止，会自动恢复
        //父进程是生产者
        while(1){
            sleep(1);
            printf("I am producer, before produce, product = %d, space =%d\n",
                semctl(semArrid,0,GETVAL),semctl(semArrid,1,GETVAL));
            semop(semArrid,&P,1);//p的是1号信号量
            printf("Produce a product\n");
            semop(semArrid,&V,1);//v的是0号信号量
            printf("I am producer, after produce, product = %d, space = %d\n",
                semctl(semArrid,0,GETVAL),semctl(semArrid,1,GETVAL));
        }
    }
}